use std::any::Any;
use tokio::sync::mpsc;
use crate::message::{Message, DynamicMessage};
use crate::errors::SendError;
use super::{MailboxBehavior, MailboxConfig, MailboxStatus};

pub struct UnboundedMailbox {
    sender: mpsc::UnboundedSender<DynamicMessage>,
    receiver: mpsc::UnboundedReceiver<DynamicMessage>,
    config: MailboxConfig,
    stats: MailboxStatus,
}

impl UnboundedMailbox {
    pub fn new(config: MailboxConfig) -> Self {
        let (sender, receiver) = mpsc::unbounded_channel();
        Self {
            sender,
            receiver,
            config,
            stats: MailboxStatus {
                messages_received: 0,
                messages_processed: 0,
            },
        }
    }
}

#[async_trait::async_trait]
impl MailboxBehavior for UnboundedMailbox {
    async fn post<T: Any + Send + Clone + 'static>(&self, msg: Message<T>) -> Result<(), SendError> {
        let dynamic_msg = msg.into_dynamic();
        self.post_dynamic(dynamic_msg).await
    }

    async fn post_dynamic(&self, msg: DynamicMessage) -> Result<(), SendError> {
        self.sender.send(msg).map_err(|_| SendError::MailboxFull)
    }

    async fn receive(&self) -> Result<Option<DynamicMessage>, SendError> {
        Ok(self.receiver.recv().await)
    }

    fn stats(&self) -> MailboxStatus {
        self.stats.clone()
    }
} 